Перейти к основному содержимому

2.03. Справочник по HTTP

Всем

Справочник по HTTP

🔹 HTTP-методы (RFC 9110, Section 9)

МетодОписаниеБезопасностьИдемпотентностьКэшируемостьОсновные заголовки, связанные с методом
GETЗапрос ресурса по URI. Не должен изменять состояние сервера.ДаДаДа (Cache-Control, Expires, ETag, Vary)If-None-Match, If-Modified-Since, Range, Accept-*
HEADКак GET, но без тела ответа. Используется для получения метаданных.ДаДаДа (как GET)Те же, что для GET
POSTОтправка данных для обработки (создание, инициирование действия).НетНет (обычно)Нет (по умолчанию; кэширование возможно при явном указании валидных Cache-Control/Expires и 200/201/304 — но практика редка)Content-Type, Content-Length, Expect: 100-continue, Transfer-Encoding
PUTЗамена ресурса по URI. Полная замена.НетДаНет (200/201/204 могут кэшироваться при Cache-Control: public)Content-Type, If-Match, If-Unmodified-Since, Content-Range (не для частичной замены — это PATCH)
DELETEУдаление ресурса.НетДаНет (200/202/204 — возможно кэширование при явных директивах)If-Match, If-Unmodified-Since
PATCHЧастичное обновление ресурса. Тело — patch-документ (RFC 5789, JSON Patch, XML Patch и др.).НетНет (если сервер не гарантирует идемпотентность патча)НетContent-Type (должен быть application/json-patch+json, application/merge-patch+json, application/xml-patch+xml и т.п.), If-Match
OPTIONSЗапрос поддерживаемых методов по URI или сервером (если *).ДаДаНетAllow в ответе
TRACEЭхо-запрос для диагностики пути запроса.ДаДаНетMax-Forwards (должен быть ≥ 0), Via
CONNECTУстановка туннеля к серверу (для HTTPS через прокси).НетНетНетИспользуется на уровне соединения; не имеет тела в запросе/ответе (кроме ошибок)

Примечания:

  • Безопасность — не изменяет состояние сервера (по RFC: does not alter the state of the server).
  • Идемпотентность — повторный вызов с теми же параметрами даёт тот же результат (не обязательно тот же ответ: 200 vs 204 допустимо, если состояние не изменилось).
  • Кэшируемость — только ответы 200, 203, 204, 206, 300, 301, 308, 404, 405, 410, 414, 501 могут быть кэшированы по умолчанию (RFC 9111, Section 4.2.2); остальные — только при явных Cache-Control/Expires.
  • Дополнительные методы: LINK, UNLINK (устарели, не в RFC); SEARCH (WebDAV, RFC 5323); REPORT (WebDAV, DAV SEARCH); MKCOL, COPY, MOVE, LOCK, UNLOCK (WebDAV, RFC 4918); BIND, REBIND, UNBIND (WebDAV, RFC 5842); ACL (WebDAV, RFC 3744); PROPFIND, PROPPATCH (WebDAV, RFC 4918); BASELINE-CONTROL, CHECKIN, CHECKOUT, MERGE, MKACTIVITY, MKWORKSPACE, UPDATE, VERSION-CONTROL (DeltaV, RFC 3253). Большинство из них не поддерживаются в общих фреймворках, но могут встречаться в специализированных системах (CMS, CMS, DMS).

🔹 Статус-коды (RFC 9110, Sections 15–17)

Класс 1xx: Информационные (не завершают запрос)

КодНазваниеПояснениеОсобенности
100ContinueСервер получил заголовки, клиент может отправлять тело.Используется при Expect: 100-continue. Сервер не должен отправлять 100, если не получал Expect: 100-continue.
101Switching ProtocolsСервер согласен перейти на протокол, указанный в Upgrade.Обязательна заголовок Upgrade и Connection: upgrade. Пример: переход на WebSocket (Upgrade: websocket).
102Processing (WebDAV, RFC 2518)Сервер принял запрос, но ещё не завершил обработку.Предотвращает таймауты у клиента при долгих операциях.
103Early Hints (RFC 8297)Промежуточный ответ с заголовками (например, Link: </style.css>; rel=preload), до формирования полного ответа.Позволяет браузеру начать предзагрузку ресурсов. Поддержка: Chrome ≥69, Firefox ≥72.
104–199Зарезервированы для будущего использования.Никогда не должны использоваться.

Класс 2xx: Успешные

КодНазваниеПояснениеОсобенности
200OKЗапрос успешен. Тело — ресурс или результат.Самый распространённый код. Для HEAD — только заголовки.
201CreatedРесурс создан.Обязателен Location с URI нового ресурса (если известен). Подходит для POST/PUT.
202AcceptedЗапрос принят, но обработка не завершена (асинхронная обработка).Ответ не должен содержать результат; может включать ссылку на статус (Location, Content-Location, Link).
203Non-Authoritative InformationОтвет получен из кэша или промежуточного узла, и информация может отличаться от исходной.Редко используется. Кэшируем.
204No ContentУспешно, но без тела.Обязательно Content-Length: 0 или отсутствие тела (Transfer-Encoding не должен быть chunked). Подходит для DELETE, PATCH, POST без ответа.
205Reset ContentКлиент должен сбросить документ (например, очистить форму).Не имеет тела. Редко поддерживается браузерами.
206Partial ContentОтвет на Range-запрос.Обязательны Content-Range, Content-Length (длина части), Accept-Ranges: bytes. Заголовок Content-Type должен быть таким же, как у полного ресурса.
207Multi-Status (WebDAV, RFC 4918)Множественные статусы в теле (XML).Используется в WebDAV-операциях (PROPFIND, LOCK).
208Already Reported (WebDAV, RFC 5842)Ресурс уже включён в предыдущий 207.Для избежания дублирования в древовидных запросах.
226IM Used (RFC 3229)Ответ — дельта от предыдущего (If-None-Match, A-IM).A-IM (Accept Instance Manipulations) — устаревший, почти не используется.

Класс 3xx: Перенаправления

КодНазваниеПояснениеОсобенности
300Multiple ChoicesНесколько вариантов представления.Редко используется. Может возвращать список (HTML, XML). Кэшируем.
301Moved PermanentlyРесурс перемещён навсегда.Кэшируем. Браузеры изменяют метод POSTGET при редиректе (RFC не обязывает, но практика такова).
302Found (ранее Moved Temporarily)Временное перенаправление.Не должен кэшироваться без Cache-Control/Expires. Браузеры также меняют POSTGET.
303See OtherОтвет доступен по другому URI, и должен быть запрошен через GET.Явно требует смены метода на GET. Используется после POST для предотвращения повторной отправки.
304Not ModifiedРесурс не изменился (If-None-Match, If-Modified-Since).Без тела. Должен включать кэш-валидирующие заголовки (ETag, Last-Modified, Cache-Control, Expires, Vary).
305Use Proxy (устарел, RFC 7231)Не использовать. Уязвимость (раскрытие прокси).
306(зарезервирован)Никогда не использовался.
307Temporary RedirectВременное перенаправление с сохранением метода и тела.Отличие от 302: клиент не должен менять POSTGET.
308Permanent RedirectПостоянное перенаправление с сохранением метода и тела.Отличие от 301: клиент не должен менять POSTGET.

Класс 4xx: Ошибки клиента

(Запрос некорректен или не может быть выполнен. Сервер понял запрос, но отказывается его исполнить.)

КодНазваниеRFC / ИсточникПояснениеОсобенности, нюансы и практика
400Bad RequestRFC 9110Синтаксическая ошибка в запросе (невалидный JSON, нарушение формата URI, неправильные заголовки и т.п.).Универсальный код при отсутствии более точного. Не следует использовать, если есть более специфичный (404, 405, 415, 422). Тело должно объяснять ошибку (например, application/problem+json).
401UnauthorizedRFC 9110Отсутствует или недействителен механизм аутентификации (WWW-Authenticate обязателен в ответе).Не путать с 403. Требует аутентификации (например, Basic, Bearer). Может быть вызвано отсутствием заголовка Authorization, просроченным токеном, неправильным realm.
402Payment RequiredRFC 9110Зарезервирован для будущего использования (платёжные системы).Де-факто используется некоторыми SaaS для «trial expired». Не стандартизирован.
403ForbiddenRFC 9110Доступ запрещён даже при успешной аутентификации (недостаточно прав, IP в чёрном списке, политики безопасности).Сервер не обязан раскрывать причину (404 иногда используется вместо 403 для сокрытия существования ресурса — security through obscurity).
404Not FoundRFC 9110Ресурс по указанному URI не найден.Кэшируем. Может быть возвращён и при 403 по соображениям безопасности.
405Method Not AllowedRFC 9110Метод не поддерживается для данного URI.Обязательный заголовок Allow в ответе (список допустимых методов, например: GET, HEAD, OPTIONS).
406Not AcceptableRFC 9110Сервер не может сгенерировать ответ, удовлетворяющий Accept-* заголовкам клиента.Редко используется (чаще возвращают 200 с наилучшим из доступного или 400).
407Proxy Authentication RequiredRFC 9110Аутентификация требуется на уровне прокси.Аналог 401, но для прокси. Обязателен заголовок Proxy-Authenticate.
408Request TimeoutRFC 9110Сервер не дождался полного запроса (например, не дождался тела при Content-Length > 0).Может быть отправлен даже после частичного получения тела. Не означает, что тело не было отправлено — только что сервер отказался ждать.
409ConflictRFC 9110Запрос конфликтует с текущим состоянием ресурса (например, уникальное ограничение БД, состояние «уже забронировано»).Тело должно содержать информацию о природе конфликта.
410GoneRFC 9110Ресурс намеренно и постоянно удалён; нет перенаправления.Кэшируем. Отличается от 404 тем, что сервер знает, что ресурс больше не будет доступен.
411Length RequiredRFC 9110Требуется заголовок Content-Length, так как сервер не поддерживает Transfer-Encoding: chunked.Актуален для очень старых серверов или специфичных API. Современные серверы почти всегда поддерживают chunked.
412Precondition FailedRFC 9110Условие в If-* заголовках (If-Match, If-Unmodified-Since) не выполнено.Используется для optimistic concurrency control (ETag, Last-Modified).
413Payload Too LargeRFC 9110Тело запроса превышает лимит сервера.Может сопровождаться заголовком Retry-After, если перегрузка временная. Ранее назывался Request Entity Too Large.
414URI Too LongRFC 9110URI превышает допустимую длину сервера.Часто возникает при GET с длинной query string (лучше использовать POST). Кэшируем.
415Unsupported Media TypeRFC 9110Content-Type в запросе не поддерживается сервером.Аналог 406, но для тела запроса. Пример: отправка application/xml, если API принимает только application/json.
416Range Not SatisfiableRFC 9110Диапазон в Range недопустим (например, bytes=500-499, bytes=9999-, если ресурс короче).Обязательный заголовок Content-Range: */длина_ресурса.
417Expectation FailedRFC 9110Сервер не может удовлетворить условие в Expect (например, Expect: 100-continue при невозможности выполнить).Редко встречается — большинство серверов просто игнорируют Expect, если не поддерживают.
418I’m a teapotRFC 2324 (HTTP Easter Eggs), RFC 7168Шуточный код из Hyper Text Coffee Pot Control Protocol (HTCPCP).Возвращается некоторыми серверами (например, Cloudflare) при 418-запросе как Easter Egg. Не для production.
421Misdirected RequestRFC 9112 (HTTP/2)Запрос направлен на хост/порт, не способный его обработать (например, HTTP/2 connection coalescing с разными сертификатами).Сервер должен закрыть соединение после отправки.
422Unprocessable ContentRFC 9110 (ранее RFC 4918 WebDAV)Синтаксис тела корректен, но семантика недопустима (например, валидный JSON, но email не соответствует формату).Предпочтителен перед 400 при валидации бизнес-логики.
423LockedRFC 4918 (WebDAV)Целевой ресурс заблокирован.Используется в WebDAV (LOCK). Может указывать на Lock-Token в заголовке.
424Failed DependencyRFC 4918 (WebDAV)Операция не выполнена из-за неудачи в зависимом запросе (например, в 207 Multi-Status).Только в WebDAV.
425Too EarlyRFC 8470Сервер отказывается обрабатывать запрос из-за риска повторной отправки (например, при Early Data в TLS 1.3 без подтверждения handshake).Связан с Early-Data: 1. Клиент должен повторить без early data.
426Upgrade RequiredRFC 9110Сервер требует обновления протокола (например, с HTTP/1.0 на HTTP/1.1).Обязательные заголовки: Upgrade, Connection: upgrade.
428Precondition RequiredRFC 6585Сервер требует условных заголовков (If-Match или If-Unmodified-Since) для предотвращения «lost update».Используется при optimistic locking. Сервер отказывается служить без ETag-проверки.
429Too Many RequestsRFC 6585Превышен лимит запросов (rate limiting).Рекомендуется Retry-After. Может сопровождаться X-RateLimit-* заголовками (не стандартизированы). Пример: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset.
431Request Header Fields Too LargeRFC 6585Заголовки запроса слишком велики (например, длинный Cookie, Authorization).Может возникать при атаке через увеличение размера заголовков.
451Unavailable For Legal ReasonsRFC 7725Доступ запрещён по юридическим причинам (цензура, блокировка по решению суда).Обязательный Link с rel="blocked-by" и URI органа, потребовавшего блокировку.

Примечания по практике:

  • Коды 400, 403, 404, 422, 429 — наиболее частые в REST API.
  • Коды 418, 419 (Laravel-specific «Session Expired»), 420 (Twitter устаревший «Enhance Your Calm»), 430 (Cloudflare — «Request Header Fields Too Large» альтернатива 431) — не стандартизированы, но встречаются.
  • 499 (Nginx: «Client Closed Request») — клиент разорвал соединение до получения ответа. Полезен для логирования и мониторинга.

Класс 5xx: Ошибки сервера

(Сервер не смог обработать корректный запрос.)

КодНазваниеRFC / ИсточникПояснениеОсобенности и распространённые причины
500Internal Server ErrorRFC 9110Общая ошибка сервера (необработанное исключение, ошибка в коде).Универсальный код при отсутствии более точного. Должен сопровождаться логированием. Избегать возвращения stack trace в production.
501Not ImplementedRFC 9110Метод или функциональность не реализована на сервере.Аналог 405, но на уровне функциональности, а не URI. Кэшируем.
502Bad GatewayRFC 9110Сервер (шлюз/прокси) получил недопустимый ответ от вышестоящего сервера.Часто при падении upstream (API, БД, микросервис). Nginx, Cloudflare возвращают при upstream prematurely closed connection.
503Service UnavailableRFC 9110Сервер временно недоступен (перегрузка, обслуживание).Желательно Retry-After. Кэшируется только при явных директивах. Отличается от 502: проблема на самом сервере, а не в upstream.
504Gateway TimeoutRFC 9110Шлюз/прокси не дождался ответа от upstream.Аналог 408, но на уровне прокси. Часто при долгих запросах к БД или внешним API.
505HTTP Version Not SupportedRFC 9110Версия HTTP в строке запроса не поддерживается.Например, HTTP/3.0 при поддержке только HTTP/1.1 и HTTP/2.
506Variant Also NegotiatesRFC 2295Циклическая ссылка в контентной неготиации (Alternates).Экзотично; почти не встречается.
507Insufficient StorageRFC 4918 (WebDAV)Недостаточно места для выполнения операции (например, загрузка).Используется в WebDAV и некоторых облачных API.
508Loop DetectedRFC 5842 (WebDAV)Обнаружен бесконечный цикл (например, в 207 Multi-Status с рекурсией).Только WebDAV.
509Bandwidth Limit ExceededНе стандартизирован (cPanel)Превышен лимит трафика.Встречается в хостингах (cPanel).
510Not ExtendedRFC 2774Сервер требует расширения (Mandatory заголовки), которое клиент не предоставил.Устаревшее; не поддерживается.
511Network Authentication RequiredRFC 6585Требуется аутентификация в сети (например, captive portal).Браузер должен открыть окно с формой (например, Wi-Fi логин). В ответе — HTML-страница с формой.
520–599Cloudflare, AWS, FastlyНестандартные коды операторов CDN/облаков.Примеры:

520 Unknown Error (Cloudflare)
521 Web Server Is Down (Cloudflare)
522 Connection Timed Out (Cloudflare)
523 Origin Is Unreachable (Cloudflare)
524 A Timeout Occurred (Cloudflare)
525 SSL Handshake Failed (Cloudflare)
526 Invalid SSL Certificate (Cloudflare)
527 Railgun Error (Cloudflare)
530 Origin Error / 1.1.1.1 Error (Cloudflare)
561 Unauthorized (AWS ALB — при аутентификации через Cognito, если токен недействителен)
Уточняйте документацию CDN/облака.

Примечания:

  • 500 должен быть финальным резервом. Стремитесь к более точным кодам (502, 503, 504, 507).
  • В микросервисах 502/504 — сигнал о проблемах в сети или upstream’ах; 500 — о проблемах в самом сервисе.
  • Избегайте 500 при валидации входных данных — это 4xx.

🔹 Заголовки HTTP

Классификация по назначению (RFC 9110, RFC 9112, RFC 9113, RFC 9114, IETF drafts, WHATWG, W3C).

1. Общие заголовки (могут быть в запросе и ответе)

ЗаголовокОписаниеСинтаксисПримечания
Cache-ControlДирективы кэширования.token [ "=" ( token / quoted-string ) ] *( OWS ";" OWS token [ "=" ( token / quoted-string ) ] )Основные директивы:

Запрос: max-age, max-stale, min-fresh, no-cache, no-store, only-if-cached
Ответ: max-age, s-maxage, public, private, no-cache, no-store, must-revalidate, proxy-revalidate, immutable, stale-while-revalidate, stale-if-error (RFC 5861), no-transform
Приоритет: s-maxage > max-age > Expires. | | Connection | Управление соединением. | token *( OWS "," OWS token ) | keep-alive, close, upgrade. Для HTTP/2+ игнорируется, кроме upgrade (для 101 Switching Protocols). | | Date | Дата и время формирования сообщения. | HTTP-date (RFC 9110, Section 5.6.7) | Обязателен в ответах, кроме 5xx. Формат: Sun, 06 Nov 1994 08:49:37 GMT. | | Pragma | Совместимость с HTTP/1.0. | token [ "=" ( token / quoted-string ) ] | Pragma: no-cacheCache-Control: no-cache в HTTP/1.0. Устарел. Игнорируется при наличии Cache-Control. | | Trailer | Имена заголовков в трейлере (при Transfer-Encoding: chunked). | field-name *( OWS "," OWS field-name ) | Заголовки, которые будут в конце тела (после 0\r\n). Например, Trailer: Server-Timing. | | Transfer-Encoding | Кодировка тела. | token *( OWS "," OWS token ) | chunked, compress, deflate, gzip, identity. Последний transfer-coding должен быть chunked или identity. Для HTTP/2+ не используется (тело всегда в frame’ах). | | Upgrade | Предложение смены протокола. | token *( "/" token *( ";" token [ "=" ( token / quoted-string ) ] ) ) *( OWS "," OWS ... ) | Пример: Upgrade: websocket, Upgrade: h2c, websocket. Обязательно с Connection: upgrade. | | Via | Цепочка прокси/шлюзов. | *( "," OWS ) ( received-protocol RWS host [ ":" port ] ) | Пример: Via: 1.1 proxy1, 1.1 proxy2 (Apache). Полезно для диагностики. |


Заголовка запроса (Request Headers)

1. Управление содержимым и согласованием (Accept-*)

ЗаголовокRFCСинтаксисПояснениеОсобенности и практика
AcceptRFC 9110, 12.5.1media-range *( OWS ";" OWS "q" "=" qvalue ) *( OWS "," OWS media-range ... ) media-range = type "/" subtype *( OWS ";" OWS parameter )Предпочтения клиента по Content-Type ответа.Пример: Accept: text/html, application/xhtml+xml;q=0.9, application/xml;q=0.8, */*;q=0.7q=1.0 по умолчанию. — Сервер не обязан следовать; может вернуть 406 при невозможности. — */* — любые типы. — Приоритет: точное совпадение > type/* > */*.
Accept-CharsetRFC 9110, 12.5.2token *( OWS ";" OWS "q" "=" qvalue ) *( OWS "," OWS token ... )Предпочтения по кодировкам символов (charset).Пример: Accept-Charset: utf-8, iso-8859-1;q=0.5. Устарел в пользу UTF-8 everywhere. Современные API игнорируют.
Accept-EncodingRFC 9110, 12.5.3token *( OWS ";" OWS "q" "=" qvalue ) *( OWS "," OWS token ... )Поддерживаемые кодировки сжатия (gzip, br, deflate, zstd, identity).Пример: Accept-Encoding: gzip, br;q=0.8, identity;q=0.5identity = без сжатия. — * = любая (редко). — q=0 = не поддерживается. — br требует TLS (в целях совместимости).
Accept-LanguageRFC 9110, 12.5.4language-range *( OWS ";" OWS "q" "=" qvalue ) *( OWS "," OWS language-range ... ) language-range = ( 1*8ALPHA *( "-" 1*8ALPHA ) ) / "*"Языковые предпочтения (ru-RU, en-US, fr).Пример: Accept-Language: ru-RU, ru;q=0.9, en-US;q=0.8, en;q=0.7q=1.0 по умолчанию. — Сервер может использовать для Content-Language, локализации ответа. — Vary: Accept-Language обязателен при разных версиях под язык.
Content-TypeRFC 9110, 8.3.1media-type [ OWS ";" OWS parameter ] *( OWS ";" OWS parameter )Тип содержимого тела запроса.Обязателен при POST/PUT/PATCH с телом. Примеры: application/json application/x-www-form-urlencoded multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW — Для multipart обязателен параметр boundary. — charset рекомендуется явно (например, application/json; charset=utf-8).

Примечание по Vary: Если сервер выдаёт разные ответы на основе Accept-*, обязательно должен возвращать Vary: Accept, Accept-Encoding, Accept-Language и т.д., иначе кэши (CDN, браузеры) могут отдать неправильную версию.


2. Условные запросы (If-*)

ЗаголовокRFCСинтаксисПояснениеОсобенности
If-MatchRFC 9110, 13.1.1"*" / ( entity-tag *( OWS "," OWS entity-tag ) )Выполнить, только если ETag ресурса соответствует одному из указанных.* = ресурс должен существовать. — Используется для optimistic concurrency: клиент отправляет ETag из предыдущего GET, сервер проверяет. — При несовпадении — 412 Precondition Failed.
If-None-MatchRFC 9110, 13.1.2"*" / ( entity-tag *( OWS "," OWS entity-tag ) )Выполнить, только если ETag не совпадает ни с одним из указанных.— Основной заголовок для кэш-валидации. — При совпадении — 304 Not Modified (для GET/HEAD), 412 (для PUT/DELETE). — * = выполнить, только если ресурс не существует (редко).
If-Modified-SinceRFC 9110, 13.1.3HTTP-dateВыполнить, только если ресурс изменён после указанной даты.— Используется в паре с Last-Modified. — Менее надёжен, чем ETag (модификация без изменения содержимого). — Игнорируется, если присутствует If-None-Match.
If-Unmodified-SinceRFC 9110, 13.1.4HTTP-dateВыполнить, только если ресурс не был изменён после даты.— Для optimistic concurrency (альтернатива If-Match). — При нарушении — 412.
If-RangeRFC 9110, 14.2.4entity-tag / HTTP-dateПрименить Range, только если ресурс не изменился (по ETag или Last-Modified).— Используется при частичных загрузках: если ресурс изменился, сервер возвращает 200 с полным телом, а не 206. — Если указан entity-tag, Last-Modified игнорируется.

Примечание:

  • Приоритет: If-Match > If-Unmodified-Since; If-None-Match > If-Modified-Since.
  • If-None-Match и If-Modified-Since могут использоваться одновременно — тогда условие ИЛИ (достаточно выполнения одного).
  • ETag должен быть слабым (W/"...") или сильным ("..."); weak подходит для If-None-Match, strong — для If-Match.

3. Диапазоны и частичная передача

ЗаголовокRFCСинтаксисПояснение
RangeRFC 9110, 14.2bytes-unit "=" byte-ranges-spec byte-ranges-spec = *( "," OWS ) ( range / suffix-byte-range-spec ) *( OWS "," ... ) range = first-byte-pos "-" [ last-byte-pos ] suffix-byte-range-spec = "-" suffix-lengthЗапрос части ресурса.
TERFC 9110, 10.1.4t-codings *( OWS "," OWS t-codings ) t-codings = "trailers" / ( transfer-coding [ OWS ";" OWS "q" "=" qvalue ] )Поддерживаемые кодировки для трейлеров и тела.

4. Кэширование (в запросе)

ЗаголовокRFCСинтаксисПояснение
Cache-Control (в запросе)RFC 9110, 5.2См. вышеДирективы от клиента к кэшу.

5. Аутентификация и авторизация

ЗаголовокRFCСинтаксисПояснениеПоддерживаемые схемы
AuthorizationRFC 9110, 11.6.2credentials credentials = auth-scheme [ 1*SP ( token68 / #auth-param ) ] auth-param = token "=" ( token / quoted-string )Учётные данные для доступа к ресурсу.

Basic: Basic base64("user:pass")
Bearer: Bearer <token> (OAuth 2.0)
Digest: Digest username="...", realm="...", nonce="...", uri="...", response="..."
AWS4-HMAC-SHA256: AWS4-HMAC-SHA256 Credential=..., SignedHeaders=..., Signature=...
Mutual: для Mutual TLS auth (редко)
Hawk, SCRAM, vapid (для WebPush) — специфичные.
— Пространства имён: token68 — base64url без padding (например, JWT).
— Заголовок не шифруется — требует HTTPS. |

ЗаголовокRFCСинтаксисПояснение
Proxy-AuthorizationRFC 9110, 11.6.3Аналогично AuthorizationДля аутентификации на прокси.

6. Сессии и идентификация

ЗаголовокRFCСинтаксисПояснениеСовременные расширения
CookieRFC 6265cookie-string = cookie-pair *( ";" OWS cookie-pair ) cookie-pair = cookie-name "=" cookie-valueОтправка сохранённых Set-Cookie.

— Может содержать несколько пар. — cookie-name и cookie-value — токены (ограниченный набор символов; в value допустимы кавычки). — Браузер отправляет только куки, соответствующие Domain, Path, Secure, HttpOnly, SameSite. — Для SameSite=Strict не отправляются в кросс-сайтовых GET (но отправляются в POST из того же origin’а).
Расширения: Cookie: __Host-sessionid=abc; __Secure-token=xyz — префиксы для усиленной безопасности (__Host- требует Secure, Path=/, отсутствие Domain; __Secure- — только Secure). |


7. Соединение и транспорт

ЗаголовокRFCСинтаксисПояснение
ExpectRFC 9110, 10.1.1token [ OWS "=" OWS token ] *( OWS "," OWS ... )Ожидания от сервера перед отправкой тела.

— Единственное стандартное значение: 100-continue. — Сервер отвечает 100 Continue или 417 Expectation Failed. — Используется для экономии bandwidth при больших телах. | | Forwarded | RFC 7239 | forwarded-element *( "," OWS forwarded-element ) forwarded-element = [ "by" "=" node ] [ ";" "for" "=" node ] [ ";" "host" "=" host ] [ ";" "proto" "=" proto ] | Стандартная замена X-Forwarded-*. | Пример: Forwarded: for=192.0.2.43, for="[2001:db8:cafe::17]", by=203.0.113.60; proto=https; host=example.comfor — клиент или предыдущий прокси. — by — этот прокси. — proto — исходная схема. — Рекомендуется использовать вместо X-Forwarded-* (если поддерживается). | | Host | RFC 9110, 7.2 | uri-host [ ":" port ] | Целевой хост и порт (обязателен в HTTP/1.1). | — Без него — 400. — Используется для виртуального хостинга. — В HTTP/2 передаётся как псевдозаголовок :authority. | | Max-Forwards | RFC 9110, 7.6.2 | 1*DIGIT | Максимальное число прокси для TRACE/OPTIONS. | — Уменьшается на 1 каждым прокси. — При 0 — обрабатывающий узел должен сам ответить. — Только для TRACE, OPTIONS; иначе игнорируется. |


8. Отладка и трассировка

ЗаголовокRFC / ИсточникСинтаксисПояснение
X-Request-IDНе стандартизированtokenУникальный ID запроса для логирования и трассировки.

— Часто UUIDv4. — Должен проксироваться без изменений. — Используется в Zipkin, Jaeger, OpenTelemetry. | | X-Correlation-ID | Не стандартизирован | token | ID корреляции для цепочки запросов (например, микросервисы). | Отличие от X-Request-ID: один Correlation-ID — на всю транзакцию, много Request-ID — на каждый вызов. | | Traceparent | W3C Trace Context | version "-" trace-id "-" parent-id "-" trace-flags | Стандартизованный заголовок для распределённой трассировки. |
version: 00trace-id: 32 hex — parent-id: 16 hex — trace-flags: 01 (sampled), 00 (not sampled) — Обязателен в OpenTelemetry. | | Tracestate | W3C Trace Context | list-member *( OWS "," OWS list-member ) list-member = key "=" value | Дополнительные данные провайдеров (vendor-specific). |
key = ( lcalpha / DIGIT / "_" / "-"/ "*" / "/" ) 0*255( lcalpha / DIGIT / "_" / "-"/ "*" / "/" ) — Пример: rojo=00f067aa0ba902b7,congo=t61rcWkgMzE |


9. Безопасность и политики

ЗаголовокRFC / ИсточникСинтаксисПояснение
OriginRFC 6454origin = scheme "://" host [ ":" port ]Происхождение запроса (для CORS и POST).

— Отправляется при POST, PUT, DELETE, PATCH, TRACE, CONNECT, и всех CORS-предварительных запросах. — Для GET/HEAD — только при кросс-сайтовом CORS. — null для data:, file:, sandbox’ed iframe’ов. | | Referer | RFC 9110, 10.1.3 | absolute-URI / partial-URI | URI откуда пришёл запрос. |
— Опечатка в названии (ReferrerReferer) — историческая. — Может быть пустым (например, при переходе с HTTPS на HTTP). — Политики: Referrer-Policy управляет его отправкой. | | DNT | Не стандартизирован (deprecated) | "1" / "0" | Do Not Track. |
1 = не отслеживать. — Игнорируется большинством сервисов. Устарел. | | Sec-Fetch-* | Fetch Metadata Request Headers | См. ниже | Метаданные о контексте запроса (для защиты от CSRF, XS-Leaks). |

Sec-Fetch-* заголовки (WHATWG Fetch, 2019+)
ЗаголовокВозможные значенияПояснение
Sec-Fetch-Sitecross-site, same-site, same-origin, noneОтношение origin’а запроса и инициатора.
Sec-Fetch-Modenavigate, same-origin, no-cors, corsРежим fetch’а.
Sec-Fetch-User?1 (true)Запрос инициирован пользователем (клик, submit).
Sec-Fetch-Destdocument, script, style, image, font, video, audio, worker, embed, object, manifest, empty и др.Назначение запроса.

— Отправляются только браузерами (не curl, HttpClient). — Позволяют серверу блокировать подозрительные запросы (например, Sec-Fetch-Dest: script на API-эндпоинте). — Требуют HTTPS (иначе не отправляются).


10. Client Hints (RFC 8942, RFC 8943)

ЗаголовокТипСинтаксисПояснение
Accept-CHОтветtoken *( OWS "," OWS token )Сервер запрашивает у клиента отправку определённых Client Hints.
Critical-CHОтветАналогично Accept-CHСервер указывает, что эти хинты критичны для корректного ответа.
Sec-CH-UAЗапросlist (Structured Fields)User Agent в структурированной форме.
Sec-CH-UA-MobileЗапрос?1 / ?0Мобильное устройство (?1 = true).
Sec-CH-UA-PlatformЗапросstring (Structured Fields)ОС: "Windows", "Android", "macOS", "Linux".
Sec-CH-UA-Platform-VersionЗапросstringВерсия ОС.
Sec-CH-UA-ArchЗапросstringАрхитектура: "x86", "x86_64", "arm", "arm64".
Sec-CH-UA-ModelЗапросstringМодель устройства (например, "Pixel 6").
Sec-CH-UA-BitnessЗапросstringРазрядность: "64", "32".
Sec-CH-UA-Full-Version-ListЗапросlistПолные версии (включая патчи).
DPRЗапросsf-decimalDevice Pixel Ratio.
Viewport-WidthЗапросsf-integerШирина viewport’а в CSS-пикселях.
WidthЗапросsf-integerЖелаемая ширина изображения (для img с sizes).

— Client Hints отправляются только по HTTPS. — Требуют явного согласия через Accept-CH или <meta http-equiv="Accept-CH">. — Используются для адаптивного контента и изображений (<picture>, srcset).


11. Экспериментальные и устаревшие

ЗаголовокСтатусПояснение
X-Forwarded-ForШироко используется (не RFC)Аналог Forwarded: for=....
X-Forwarded-HostАналог Forwarded: host=....
X-Forwarded-ProtoАналог Forwarded: proto=....
X-Powered-ByУстаревшийИнформация о стеке (PHP/8.2, Express).
X-AspNet-Version, X-RuntimeСпецифичные для платформ.
X-Content-Type-OptionsУстаревший (но поддерживается)nosniff — запрет MIME-sniffing’а.
X-Frame-OptionsУстаревшийDENY, SAMEORIGIN, ALLOW-FROM uri
X-XSS-ProtectionУстаревший0, 1, 1; mode=block
Public-Key-PinsУдалён (2019)HPKP — уязвимость к DoS.

Заголовки ответа (Response Headers)

1. Управление содержимым

ЗаголовокRFCСинтаксисПояснениеОсобенности
Content-TypeRFC 9110, 8.3.1media-type [ OWS ";" OWS parameter ] *( OWS ";" OWS parameter )Тип содержимого тела ответа.

— Обязателен при наличии тела (кроме 204, 304). — Примеры:  text/html; charset=utf-8application/json; charset=utf-8image/jpegmultipart/byteranges; boundary=... (при 206) — Параметр charset рекомендуется явно указывать для текстовых типов. — Для text/* по умолчанию ISO-8859-1; игнорируется, если указан charset. — Браузеры могут выполнять MIME-sniffing, если не указан X-Content-Type-Options: nosniff (устаревший, но эффективный) или если тип text/plain. | | Content-Length | RFC 9110, 6.3.2 | 1*DIGIT | Длина тела в октетах. |
— Обязателен, если нет Transfer-Encoding: chunked или Content-Range. — Не должен присутствовать при Transfer-Encoding: chunked, 204, 304, 1xx, 204. — При несоответствии поведение неопределено (обрезка/дозагрузка). | | Content-Encoding | RFC 9110, 8.4 | token *( OWS "," OWS token ) | Кодировки, применённые к телу после Content-Type. |
— Пример: Content-Encoding: gzip — Порядок важен: Content-Encoding: br, gzip = сначала br, потом gzip (редко). — Должен соответствовать Accept-Encoding. — Не для сжатия контента (например, ZIP-файла), а для транспортного сжатия. Для архивов — Content-Type: application/zip. | | Content-Language | RFC 9110, 8.6 | language-tag *( OWS "," OWS language-tag ) | Язык содержимого. |
— Пример: Content-Language: ru, en — Не влияет на Accept-Language, но может использоваться для Vary. — Для многоязычных документов — перечисление. | | Content-Location | RFC 9110, 8.7 | absolute-URI / partial-URI | URI, по которому доступно именно это представление. |
— Отличается от Location (редирект) и Content-Location (идентичность). — Может совпадать с запрошенным URI или быть другим (например, canonical URL). — При 201 Created может дублировать Location, но семантически: Location — где создан, Content-Location — где находится текущее представление. | | Content-Range | RFC 9110, 14.4 | range-unit OWS "/" OWS ( range-resp / "*" ) range-resp = range-unit "=" range "/" complete-length | Диапазон в ответе (для 206). |
— Пример: Content-Range: bytes 200-1000/67589 — При 416: Content-Range: bytes */67589* — если длина неизвестна (редко). | | Content-Disposition | RFC 6266 | disposition-type *( OWS ";" OWS disposition-parm ) disposition-parm = "filename" "=" value / "filename*" "=" ext-value / token "=" value | Как обрабатывать тело (отображать inline или как attachment). |
— Типы: inline (по умолчанию), attachment, form-datamultipart). — Параметры:  filename="report.pdf" — для ASCII  filename*=UTF-8''%D0%9E%D1%82%D1%87%D0%B5%D1%82.pdf — RFC 5987, для Unicode — Обязателен при скачивании файлов через <a download>. |


2. Кэширование

ЗаголовокRFCСинтаксисПояснениеВзаимодействия
Cache-ControlRFC 9110, 5.2См. ранееДирективы кэширования от сервера.

public: может кэшироваться любым кэшем (включая CDN). — private: только клиентским кэшем (не CDN). — max-age=N: свежесть = N секунд. — s-maxage=N: для shared-кэшей (CDN), приоритет над max-age. — must-revalidate: при устаревании — обязательно валидировать. — stale-while-revalidate=N: можно отдавать устаревший, пока идёт фоновая валидация. — immutable: содержимое никогда не меняется (для статики с хэшем в имени). | | Expires | RFC 9110, 5.3 | HTTP-date | Абсолютная дата устаревания. |
— Игнорируется при наличии Cache-Control: max-age или s-maxage. — Формат: Wed, 21 Oct 2025 07:28:00 GMT. — Ошибки в формате → Expires игнорируется. | | ETag | RFC 9110, 8.8.3 | entity-tag entity-tag = [ "W/" ] DQUOTE 1*etagc DQUOTE | Уникальный идентификатор версии ресурса. |
— Strong: "abc" — байт-в-байт идентичность. — Weak: W/"abc" — семантическая эквивалентность. — Должен быть уникальным в пределах URI. — Рекомендуется хэш (SHA-256) или хэш содержимого + timestamp. | | Last-Modified | RFC 9110, 8.8.2 | HTTP-date | Дата последней модификации. |
— Используется с If-Modified-Since, If-Unmodified-Since. — Менее надёжен, чем ETag (модификация без изменения содержимого). — Сервер должен учитывать точность файловой системы (часто округляется до секунды). | | Vary | RFC 9110, 12.5.5 | field-name *( OWS "," OWS field-name ) | Заголовки запроса, от которых зависит содержимое ответа. |
Обязателен, если ответ зависит от Accept, Accept-Encoding, Accept-Language, Origin и т.д. — Пример: Vary: Accept-Encoding, AcceptVary: * — не кэшировать (редко). | | Age | RFC 9110, 5.1 | 1*DIGIT | Время в секундах, прошедшее с генерации ответа (в shared-кэше). |
— Устанавливается прокси/CDN. — Age = now - Date. | | Warning | RFC 9110, 5.5 | warn-code OWS warn-agent OWS warn-text [ OWS warn-date ] | Предупреждения о работе кэша. |
— Пример: 110 anderson/1.3.37 "Response is stale" — Коды: 110 — устаревший, 111 — повторная валидация не удалась, 112 — отсоединение, 199 — прочее. |


3. Аутентификация

ЗаголовокRFCСинтаксисПояснение
WWW-AuthenticateRFC 9110, 11.6.1challenge *( OWS "," OWS challenge ) challenge = auth-scheme [ 1*SP ( token68 / #auth-param ) ]Требования к аутентификации (401).

— Примеры:  WWW-Authenticate: Basic realm="Access to staging site"WWW-Authenticate: Bearer realm="example", error="invalid_token", error_description="..."realm — обязательный параметр для Basic, Digest. — Для Bearererror, error_description, scope, realm. | | Proxy-Authenticate | RFC 9110, 11.6.3 | Аналогично WWW-Authenticate | Требования к аутентификации на прокси (407). |


4. Сессии

ЗаголовокRFCСинтаксисПояснениеАтрибуты и расширения
Set-CookieRFC 6265, RFC 6265bis (draft)cookie-pair *( ";" OWS cookie-av ) cookie-av = expires-av / max-age-av / domain-av / path-av / secure-av / httponly-av / samesite-av / partitioned-av / priority-avУстановка куки.

cookie-pair = cookie-name "=" cookie-value
— Атрибуты:  Expires=Wed, 21 Oct 2025 07:28:00 GMTMax-Age=3600 (приоритет над Expires)  Domain=example.com (включает поддомены)  Path=/adminSecure — только по HTTPS  HttpOnly — недоступен из JS (document.cookie)  SameSite=Strict|Lax|NonePartitioned (RFC 9645, Chrome ≥118) — изоляция в embed’ах (3PCD)  Priority=High|Medium|Low (Chrome-only, устаревает в пользу partitioned) — Безопасные префиксы:  __Host- — требует Secure, Path=/, отсутствие Domain__Secure- — требует SecureSameSite=None требует Secure. |

SameSite подробно:

  • Strict: не отправляется в кросс-сайтовых запросах вообще.
  • Lax: отправляется только в «безопасных» кросс-сайтовых GET (ссылки), но не в POST, iframe, img.
  • None: отправляется всегда (требует Secure).
    — По умолчанию (если не указано) — Lax (современные браузеры).

5. Перенаправление и навигация

ЗаголовокRFCСинтаксисПояснение
LocationRFC 9110, 10.2.2absolute-URI / partial-URIURI для перенаправления (201, 3xx).

— Для 201 Created — желательно. — Для 3xxобязательно. — Может быть относительным (браузер резолвит относительно текущего Host). | | Refresh | Не RFC (HTML Living Standard) | delta-seconds [ ";" OWS "url" "=" DQUOTE uri DQUOTE ] | Автообновление/редирект на стороне клиента. |
— Пример: Refresh: 5; url=/new-location — Устаревший; использовать <meta http-equiv="refresh"> или 3xx. — Не надёжен (блокируется некоторыми браузерами). | | Retry-After | RFC 9110, 10.2.3 | HTTP-date / 1*DIGIT | Когда повторить запрос (503, 429, 3xx). |
— Пример: Retry-After: 120 (секунд) или Retry-After: Wed, 21 Oct 2025 08:00:00 GMT — Используется клиентами (браузеры — редко; API-клиенты — да). |


6. Безопасность

ЗаголовокRFC / ИсточникСинтаксисПояснениеСостояние
Strict-Transport-SecurityRFC 6797max-age=delta-seconds [; includeSubDomains] [; preload]Принудительное использование HTTPS.

max-age=31536000 — 1 год. — includeSubDomains — для всех поддоменов. — preload — запрос включения в HSTS preload list (Chrome, Firefox). | | Content-Security-Policy | CSP Level 3 | policy-directive *( ";" OWS policy-directive ) | Ограничения на источники ресурсов. |
— Пример: default-src 'self'; script-src 'self' https://cdn.example.com; object-src 'none' — Директивы: default-src, script-src, style-src, img-src, font-src, connect-src, frame-src, child-src, frame-ancestors, form-action, base-uri, sandbox, report-uri, report-to и др. — frame-ancestors заменяет X-Frame-Options. | | X-Content-Type-Options | Не RFC (Microsoft) | nosniff | Запрет MIME-sniffing’а. |
— Поддерживается всеми браузерами. — Эффективен для script, style, image (если Content-Type не соответствует ожидаемому — блокировка). | | Referrer-Policy | Referrer Policy | token *( OWS "," OWS token ) | Управление отправкой Referer. |
— Значения: no-referrer, no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url. — По умолчанию: strict-origin-when-cross-origin (совр. браузеры). | | Permissions-Policy | Permissions Policy | directive *( "," OWS directive ) directive = token [ "=" *( token / DQUOTE token *( OWS token ) DQUOTE ) ] | Контроль над API браузера (камера, геолокация и др.). |
— Пример: camera=(), geolocation=(self "https://trusted.com") — Заменяет устаревший Feature-Policy. | | Cross-Origin-Embedder-Policy | COEP | require-corp / credentialless | Требование CORS для embed’ов (включает SharedArrayBuffer). |
require-corp: все embed’ы (<script>, <img>, fetch()) должны иметь Cross-Origin-Resource-Policy или CORS headers. — credentialless: анонимные запросы (без кук, TLS client cert). | | Cross-Origin-Opener-Policy | COOP | unsafe-none / same-origin-allow-popups / same-origin | Изоляция окон (защита от XS-Leaks). |
same-origin: запрет window.opener для кросс-сайтовых окон. — Требуется для SharedArrayBuffer. | | Cross-Origin-Resource-Policy | CORP | same-site / same-origin / cross-origin | Ограничение embed’ов на уровне ресурса. |
same-site: только с того же eTLD+1. — same-origin: только с того же origin’а. — Поддерживается не всеми браузерами. | | Clear-Site-Data | Clear Site Data | "*" / DQUOTE token *( OWS token ) DQUOTE | Очистка данных сайта. |
Clear-Site-Data: "cache", "cookies", "storage", "executionContexts" — Используется при logout. |


7. Мониторинг и отладка

ЗаголовокRFC / ИсточникСинтаксисПояснение
ServerRFC 9110, 10.2.4product *( OWS "/" OWS product-version ) *( OWS product ... )Информация о сервере.

— Пример: Server: nginx/1.24.0Рекомендуется минимизировать или удалять (раскрытие версий — риск). | | Server-Timing | Server Timing | metric-name [ "=" metric-value ] [ ";" OWS "desc" "=" DQUOTE description DQUOTE ] *( "," ... ) | Метрики производительности. |
— Пример: Server-Timing: db;dur=53, app;dur=120.5, cache;desc="redis" — Отображается в DevTools (Chrome, Firefox). — Используется для RUM (Real User Monitoring). | | Report-To | Reporting API | JSON-объект (см. RFC 9260) | Конфигурация endpoints для отчётов. |
— Пример: Report-To: { "group": "default", "max_age": 10886400, "endpoints": [{ "url": "https://example.com/reports" }], "include_subdomains": true } — Используется для NEL, CSP, Deprecation и др. | | NEL | Network Error Logging | JSON-объект | Конфигурация логирования сетевых ошибок. |
— Пример: NEL: { "report_to": "default", "max_age": 10886400, "success_fraction": 0.0, "failure_fraction": 1.0 } |


8. CORS и межсайтовые политики

ЗаголовокRFCСинтаксисПояснение
Access-Control-Allow-OriginRFC 6452origin / "*"Разрешённые origin’ы.

* — только если Access-Control-Allow-Credentials: false (по умолчанию). — При credentials: trueтолько конкретный origin, не *. | | Access-Control-Allow-Methods | — | method *( OWS "," OWS method ) | Разрешённые методы (для preflight). |
— Пример: GET, POST, PUT — Обязателен в preflight-ответе (204/200). | | Access-Control-Allow-Headers | — | field-name *( OWS "," OWS field-name ) | Разрешённые заголовки (для preflight). |
— Обязательные: Authorization, Content-Type (если не application/x-www-form-urlencoded, multipart/form-data, text/plain). | | Access-Control-Allow-Credentials | — | "true" | Разрешение credentials (куки, TLS cert, Authorization). |
— Только true (нет false). — При trueAccess-Control-Allow-Origin не может быть *. | | Access-Control-Max-Age | — | 1*DIGIT | Кэширование preflight-ответа (в секундах). |
— Максимум в браузерах: Chrome — 600, Firefox — 86400. — 0 — не кэшировать. | | Access-Control-Expose-Headers | — | field-name *( OWS "," OWS field-name ) | Заголовки, доступные в getResponseHeader(). |
— По умолчанию: Cache-Control, Content-Language, Content-Length, Content-Type, Expires, Last-Modified, Pragma. — Для кастомных (X-RateLimit-*) — необходимо указать. | | Access-Control-Request-Method | — | method | Метод, который будет использован в основном запросе (в preflight). | Только в запросе. | | Access-Control-Request-Headers | — | field-name *( OWS "," OWS field-name ) | Заголовки, которые будут отправлены в основном запросе. | Только в запросе. |


9. Client Hints и контентная адаптация

ЗаголовокRFCСинтаксисПояснение
Accept-CHRFC 8942token *( OWS "," OWS token )Запрос Client Hints от клиента.
Accept-CH-LifetimeУстаревший (заменён Critical-CH)1*DIGITВремя (в секундах), в течение которого клиент должен отправлять указанные хинты.
Critical-CHRFC 8942Аналогично Accept-CHУказание критичности хинтов.
VariantsRFC 8942token "=" variant-value *( OWS "," OWS variant-value )Информация о вариантах контента (для прокси).
Variant-KeyRFC 8942token *( OWS "," OWS token )Какой вариант был выбран.

10. Экспериментальные и устаревшие

ЗаголовокСтатусПояснение
P3PУстаревшийPlatform for Privacy Preferences.
Public-Key-PinsУдалёнHTTP Public Key Pinning.
Feature-PolicyУстаревшийЗаменён на Permissions-Policy.
Timing-Allow-OriginУстаревшийРазрешить доступ к PerformanceTiming.

🔹 Тело сообщения (Message Body)

Тело присутствует в запросе или ответе, если:

  • метод подразумевает тело (POST, PUT, PATCH, REPORT, и др.), и
  • статус-код допускает тело (2xx, 4xx, 5xx, кроме 204, 304, 1xx), и
  • присутствует Content-Length или Transfer-Encoding: chunked или multipart/byteranges.

Форматы тела и их особенности

MIME-типRFC / СпецификацияСтруктураПрименениеОсобенности
application/jsonRFC 8259UTF-8 JSON (рекомендуется), без BOMREST API, конфиги, обмен данными

charset в Content-Type не обязателен, но рекомендуется: application/json; charset=utf-8. — Сервер должен проверять Content-Type, а не полагаться на Accept. — Ошибки парсинга → 400 Bad Request. | | application/x-www-form-urlencoded | WHATWG URL | key=value&key2=value2, application/x-www-form-urlencoded | HTML-формы (method="POST"), OAuth2 application/x-www-form-urlencoded |
— Кодирование: application/x-www-form-urlencoded — аналог encodeURIComponent, но с заменой пробелов на +. — Максимальная длина — ограничена сервером (часто 1–10 МБ). — Не поддерживает двоичные данные. | | multipart/form-data | RFC 7578 | --boundary, части с Content-Disposition: form-data; name="...", filename="...", Content-Type | Загрузка файлов, смешанные данные |
— Обязателен параметр boundary в Content-Type. — Части могут иметь разные Content-Type. — Поддерживается всеми фреймворками и браузерами. — Для файлов: Content-Disposition: form-data; name="file"; filename="test.pdf". — filename* — RFC 5987 для Unicode. | | text/plain | RFC 2046 | Произвольный текст | Логи, простые ответы, fetch() с response.text() |
— Браузеры могут применять MIME-sniffing → использовать X-Content-Type-Options: nosniff, если важно. — charset желателен. | | application/octet-stream | RFC 2046 | Произвольные байты | Бинарные данные без метаданных (резервный тип) |
— По умолчанию для неизвестных типов. — Часто используется для скачивания (с Content-Disposition: attachment). | | multipart/byteranges | RFC 9110, 14.5 | --boundary, части с Content-Range, Content-Type | Ответ на Range с несколькими диапазонами |
— Сервер вправе игнорировать множественные Range и вернуть 200. — Поддержка в браузерах ограничена. | | text/event-stream | HTML Living Standard | field: value\n\n, data: ..., id:, event:, retry: | Server-Sent Events (SSE) |
— Только text/event-stream; charset=utf-8. — Должен быть Cache-Control: no-cache. — Соединение держится открытым (Transfer-Encoding: chunked). | | application/gzip, application/deflate, application/br, application/zstd | Не RFC | Сжатый поток | Передача архивов (не путать с Content-Encoding) |
— Отличается от Content-Encoding: это семантическое сжатие (файл-архив), а не транспортное. — Сервер не распаковывает автоматически. — Пример: Content-Type: application/gzip + Content-Disposition: attachment; filename="data.json.gz". | | application/xml, application/soap+xml | RFC 7303 | XML | SOAP, WebDAV, legacy API |
charset желателен. — +xml подтипы получают special treatment в браузерах (XML-парсинг, XSLT). | | application/pdf, image/*, audio/*, video/* | IANA | Бинарный формат | Документы, медиа |
— Браузеры могут рендерить inline (<embed>, <object>, <video>). — Для Content-Disposition: inline — открытие в браузере; attachment — скачивание. |

Важно:

  • Тело не должно присутствовать в HEAD, 204, 304, 1xx.
  • При Transfer-Encoding: chunked тело разбито на чанки:
    [chunk-size in hex]\r\n
    [chunk-data]\r\n
    ...
    0\r\n
    [trailer headers, if any]\r\n
    \r\n
  • Content-Length и Transfer-Encoding взаимоисключающи (если есть TE: chunked, Content-Length игнорируется).
  • Для HTTP/2 и HTTP/3 тело передаётся в DATA фреймах; Transfer-Encoding: chunked не используется.

🔹 Кодировки и сжатие (Content-Encoding)

КодировкаRFC / СпецификацияАлгоритмHeader checksumStream formatПоддержка
gzipRFC 1952DEFLATE + 10-байтный заголовок + 8-байтный trailer (CRC-32, ISIZE)CRC-32ID1=0x1F, ID2=0x8B, CM=8 (deflate), FLG, MTIME, XFL, OS, [extra], [name], [comment], CRC32, ISIZEВсе браузеры, серверы
deflateRFC 1951Чистый DEFLATE (без заголовка zlib или gzip)НетRaw DEFLATE stream (RFC 1951)Нестандартно: многие серверы отправляют zlib-обёрнутый поток (RFC 1950), что вызывает ошибки в IE. Избегать в пользу gzip/br.
brRFC 7932Brotli (LZ77 + Huffman + контекстное моделирование)Нет (встроенный в формат)simple, static, dynamic метаблокиChrome ≥49, Firefox ≥44, Node.js ≥10.16
zstdRFC 8878Zstandard (Facebook)XXH64 (опционально)Frame format: magic, frame header, blocks, optional checksumПоддержка растёт: Cloudflare, Apache, Nginx ≥1.19.7, Chrome ≥110 (экспериментально)
compressУстаревший (LZW)LZWНетUNIX compress formatНе поддерживается.

Рекомендации:

  • Приоритет клиентского Accept-Encoding: br, zstd, gzip, deflate.
  • br даёт на 15–20% лучшее сжатие, чем gzip, при сопоставимой скорости декомпрессии.
  • zstd — выше скорость сжатия/декомпрессии при сопоставимом с br сжатии.
  • Для динамических ответов — gzip (универсально). Для статики — br + fallback на gzip.
  • Не сжимать уже сжатые данные (JPEG, PNG, MP4, ZIP) — увеличит размер.

🔹 Аутентификация: схемы и безопасность

СхемаRFC / СпецификацияСинтаксис AuthorizationБезопасностьИспользование
BasicRFC 7617Basic base64(user:password)Низкая (credentials в открытом виде)Требует HTTPS. Для внутренних API, dev-сред.
BearerRFC 6750Bearer <token>Зависит от токена (JWT, opaque)OAuth 2.0, OpenID Connect. Токен должен быть краткосрочным, с scope, aud.
DigestRFC 7616Digest username="...", realm="...", nonce="...", uri="...", response="hash(...)", ...Средняя (защита от passive sniffing)Устаревает. Уязвим к MITM и replay (без qop=auth-int).
AWS4-HMAC-SHA256AWS Signature Version 4AWS4-HMAC-SHA256 Credential=AKI..., SignedHeaders=host;x-amz-date, Signature=...Высокая (подпись запроса)AWS API, совместимые S3-сервисы.
HawkHawk (Eran Hammer)Hawk id="...", ts="...", nonce="...", mac="...", ext="..."Высокая (MAC на основе временной метки)Устаревает (автор отозвал).
SCRAMRFC 5802, RFC 7804SCRAM-<alg> data="..."Высокая (защита от offline-атак)IMAP, XMPP, PostgreSQL SASL. Редко в HTTP.
vapidRFC 8292vapid t="...", k="..."СредняяWeb Push: подписка на уведомления.
MutualRFC 8120Mutual ...Очень высокая (двусторонняя аутентификация)Японские гос. сервисы. Требует клиентских сертификатов.

Общие рекомендации:

  • Всегда использовать HTTPS.
  • Избегать Basic в production.
  • Для Bearer — валидировать iss, aud, exp, iat, nbf, scope.
  • Хранить токены в HttpOnly, Secure, SameSite=Strict куках (не в localStorage).
  • Реализовывать refresh tokens с коротким сроком и rotation.

Атрибуты (RFC 6265bis, Chrome ≥118+)

АтрибутЗначениеОбязательностьПояснение
SecureфлагрекомендуетсяТолько по HTTPS. Обязателен при SameSite=None.
HttpOnlyфлагрекомендуетсяНедоступен из JS (document.cookie). Защита от XSS.
SameSiteStrict | Lax | NoneрекомендуетсяКонтроль кросс-сайтовых отправок. None → требует Secure.
PathстрокаопциональноПо умолчанию — путь запроса (не рекомендуется). Лучше явно /.
DomainдоменопциональноПо умолчанию — текущий хост (без поддоменов). Domain=example.com → включает *.example.com.
Max-Ageцелое ≥ 0рекомендуетсяПриоритет над Expires. 0 — удалить.
ExpiresHTTP-dateустареваетАльтернатива Max-Age.
PartitionedфлагэкспериментальноИзоляция куки в embed’ах (3PCD, Chrome ≥118, RFC 9645). Требует __Host- или __Secure-.
PriorityHigh | Medium | LowустареваетChrome-only, заменён на Partitioned.

Безопасные префиксы (RFC 6265bis)

ПрефиксТребованияЦель
__Host-Secure, Path=/, отсутствие DomainБолее строгая привязка к хосту и пути.
__Secure-SecureЗащита от отправки по HTTP.

Пример безопасного сессионного куки:

Set-Cookie: __Host-sessionid=abc123; Secure; HttpOnly; SameSite=Lax; Max-Age=3600; Path=/

🔹 Кэширование: продвинутые сценарии

Валидация и обновление

СценарийЗапрос клиентаОтвет сервераРезультат
Свежий кэшCache-Control: max-age=3600, ETag: "abc"Кэш используется (возраст < 3600).
Устаревший → валидацияIf-None-Match: "abc"304 Not Modified, ETag: "abc", Cache-Control: max-age=3600Кэш обновлён (свежесть = 3600 с момента ответа).
Устаревший → изменёнIf-None-Match: "abc"200 OK, ETag: "def", Cache-Control: max-age=3600Кэш заменён.
Устаревший + must-revalidateCache-Control: max-age=3600, must-revalidateПри истечении — обязательно If-None-Match.

stale-while-revalidate и stale-if-error

ДирективаПоведение
stale-while-revalidate=60Можно отдавать устаревший контент, пока в фоне идёт валидация (до 60 сек).
stale-if-error=86400При ошибке сервера (5xx) можно отдавать устаревший контент (до 1 дня).

Пример для CDN:

Cache-Control: public, max-age=60, s-maxage=300, stale-while-revalidate=60, stale-if-error=86400

🔹 Соединения и транспорт

Заголовок/ПараметрRFCПояснение
Connection: keep-aliveHTTP/1.1 по умолчаниюСохранение соединения для последующих запросов.
Keep-Alive: timeout=5, max=1000Устаревший (HTTP/1.0)timeout — секунд до закрытия, max — макс. запросов на соединение.
Upgrade: h2cRFC 7540HTTP/2 Cleartext (без TLS), редко используется.
Alt-SvcRFC 7838Альтернативные сервисы: Alt-Svc: h3=":443"; ma=3600, h2=":443"; ma=3600
Early-DataRFC 8470Early-Data: 1 — запрос отправлен в 0-RTT TLS 1.3. Сервер может ответить 425 Too Early.

🔹 HTTP/2 (RFC 9113) и HTTP/3 (RFC 9114) — ключевые отличия

ФичаHTTP/1.1HTTP/2HTTP/3
Версиятекстовая строка (HTTP/1.1)PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n → SETTINGS frameQUIC (UDP), версия в TLS ALPN (h3)
Заголовкитекстовые, повторяютсяHPACK-сжатие (Huffman + динамический словарь)QPACK (асинхронный HPACK, безопасный от блокировок)
Мультиплексированиенет (ограничение по 6 соединений/хост)есть (streams, frames)есть (streams в QUIC)
Приоритезациянетвеса и зависимости (устарело в RFC 9113)нет (оставлено приложениям)
Server Pushнетесть (PUSH_PROMISE), устарелоудалено
Псевдозаголовкинет:method, :scheme, :authority, :pathте же
Потоковая обработкачанки (Transfer-Encoding: chunked)DATA framesSTREAM frames
TLSопциональнорекомендуется (но h2c разрешён)обязательно (QUIC встроен в TLS 1.3)
Потеря пакетаблокирует всё соединениеблокирует только один streamне блокирует другие streams (QUIC)

Псевдозаголовки (HTTP/2, HTTP/3):

  • :method — метод (обязателен в запросе)
  • :schemehttp/https (обязателен)
  • :authority — аналог Host (обязателен; заменяет Host)
  • :path — URI-путь + query (обязателен)
  • :status — статус-код (в ответе)

HTTP/3 особенности:

  • Порт по умолчанию — 443 (UDP).
  • Поддержка 0-RTT (early data), но с риском replay → 425 Too Early.
  • Alt-Svc используется для миграции с HTTP/2 на HTTP/3.

🔹 Трассировка и мониторинг

1. Server-Timing (W3C Recommendation, 2019)

Передача метрик производительности от сервера клиенту (браузеру или мониторинговой системе).

Синтаксис

Server-Timing: [metric-name][=metric-value][;desc="description"][, ...]
  • metric-name — токен (например, db, cache, app).
  • metric-value — неотрицательное число (по умолчанию 0).
  • desc — строка в кавычках (опционально, для пояснения).

Примеры

Server-Timing: db;dur=45.2, cache;dur=12, app;dur=118.7;desc="auth+validation"
Server-Timing: miss, db;dur=200, total;dur=215

Поддержка

  • Браузеры: Chrome ≥60, Firefox ≥60, Edge ≥79.
  • Отображается в DevTools → Network → Timing → "Server Timing".
  • Доступен через JavaScript:
    performance.getEntriesByType('navigation')[0].serverTiming
    // [{ name: "db", duration: 45.2, description: "" }, ...]

Рекомендации

  • Измерять этапы: db, cache, auth, serialization, total.
  • Не включать чувствительные данные в desc.
  • Для микросервисов — агрегировать или проксировать без дублирования имён.

2. Reporting API (RFC 9260)

Единый механизм отправки отчётов о проблемах (CSP, NEL, deprecation, intervention, crash).

Report-To

Объявляет endpoint’ы для отчётов. Устанавливается в ответе.

Синтаксис (JSON)
Report-To: {
"group": "default",
"max_age": 10886400,
"endpoints": [
{ "url": "https://example.com/reports" }
],
"include_subdomains": true
}
  • group — имя группы (должно совпадать с report_to в других заголовках).
  • max_age — срок жизни конфигурации (в секундах).
  • endpoints — массив URL’ов (поддерживается fallback).
  • include_subdomains — применять к поддоменам.

Типы отчётов

ТипИсточникПример payload
CSPContent-Security-Policy: ...; report-to=default{ "csp-report": { "document-uri": "...", "violated-directive": "script-src", ... } }
NELNEL: { "report_to": "default", "max_age": 86400 }{ "age": 120, "type": "http", "url": "...", "status_code": 500, "elapsed_time": 300, ... }
DeprecationБраузер{ "type": "deprecation", "url": "...", "id": "PrefixedWebSocket", ... }
InterventionБраузер{ "type": "intervention", "url": "...", "id": "AudioContextAutoplay", ... }
CrashБраузер (экспериментально){ "type": "crash", ... }

NEL (Network Error Logging) — логирует сетевые ошибки (DNS failure, TCP timeout, TLS handshake fail), недоступные через JS.

Требования к endpoint’у

  • Должен принимать POST с Content-Type: application/reports+json.
  • Возвращать 200 OK (иначе клиент повторит).
  • Обрабатывать батчи (массив отчётов в одном теле).

🔹 Безопасность: углублённый разбор

1. Content Security Policy (CSP Level 3)

Контроль источников выполнения и загрузки ресурсов.

Синтаксис

Content-Security-Policy: directive value [; directive value ...]

Ключевые директивы

ДирективаНазначениеПример
default-srcfallback для всех *-src, кроме frame-ancestors, form-action, base-uri, sandboxdefault-src 'self'
script-srcисточники скриптовscript-src 'self' https://cdn.example.com 'unsafe-inline'
style-srcисточники стилейstyle-src 'self' 'unsafe-inline'
img-srcизображенияimg-src * data: blob:
font-srcшрифтыfont-src 'self' https://fonts.gstatic.com
connect-srcfetch, XHR, WebSocket, EventSourceconnect-src 'self' https://api.example.com
frame-src<iframe>, <frame>frame-src 'none'
frame-ancestorsкто может встроить страницу (<iframe>, <object>, <embed>)frame-ancestors 'self' https://trusted.com
form-actionкуда можно отправлять формыform-action 'self'
base-uriдопустимые значения <base href>base-uri 'self'
object-src<object>, <embed>, <applet>object-src 'none'
worker-srcWorker, SharedWorkerworker-src 'self' blob:
manifest-srcWeb App Manifestmanifest-src 'self'
media-src<audio>, <video>media-src *
prefetch-srcrel=prefetch, prerenderprefetch-src https://cdn.example.com
report-to / report-uriотправка отчётовreport-to default

Источники (source expressions)

ВыражениеПояснение
'self'тот же origin (scheme, host, port)
https:любой HTTPS-ресурс
*.example.comподдомены
'unsafe-inline'inline-скрипты/стили (избегать)
'unsafe-eval'eval(), new Function() (избегать)
'nonce-<base64>'разрешить скрипт/стиль с nonce="<base64>"
'sha256-<base64>'хэш содержимого (только для inline)
data:data: URL
blob:Blob URL
'strict-dynamic'доверять только динамически созданным скриптам (с nonce/hash)

Режимы

  • enforce (Content-Security-Policy) — блокирует нарушения.
  • report-only (Content-Security-Policy-Report-Only) — только логирует.

Рекомендации:

  • Начинать с report-only, собирать отчёты, анализировать, затем включать enforce.
  • Избегать 'unsafe-inline', 'unsafe-eval'.
  • Использовать nonce или hash для inline-контента.
  • Указывать object-src 'none', base-uri 'self', form-action 'self' по умолчанию.

2. Изоляция: COOP, COEP, CORP

ЗаголовокRFCЗначениеЭффект
Cross-Origin-Opener-Policy: same-originRFC 9675Запрет доступа к window.opener из кросс-сайтовых оконЗащита от XS-Leaks, включение SharedArrayBuffer
Cross-Origin-Embedder-Policy: require-corpRFC 9675Все embed’ы (<script>, <img>, fetch()) должны иметь CORS или Cross-Origin-Resource-PolicyТребуется для SharedArrayBuffer, предотвращает side-channel атаки
Cross-Origin-Resource-Policy: same-originRFC 9675Ресурс может быть загружен только с того же origin’аЗащита от встраивания в кросс-сайтовые страницы

Требования для SharedArrayBuffer

  • Cross-Origin-Opener-Policy: same-origin
  • Cross-Origin-Embedder-Policy: require-corp
  • Все сторонние ресурсы — с CORS или CORP: same-site/same-origin.

3. Clear-Site-Data

Очистка данных при logout или уничтожении сессии.

Синтаксис

Clear-Site-Data: "<type>" [,"<type>"]*
  • "cache" — HTTP-кэш
  • "cookies" — все куки для origin’а
  • "storage"localStorage, sessionStorage, IndexedDB, Cache API
  • "executionContexts" — закрытие всех вкладок/воркеров для origin’а
  • "*" — всё вышеперечисленное

Пример

Clear-Site-Data: "cache", "cookies", "storage"

Ограничения:

  • Работает только по HTTPS.
  • Не удаляет Service Worker (требуется явный serviceWorker.unregister()).
  • executionContexts — поддержка ограничена.

4. Permissions-Policy (бывший Feature-Policy)

Контроль над powerful API браузера.

Синтаксис

Permissions-Policy: feature=(self "https://trusted.com"), other-feature=()

Примеры

Permissions-Policy: geolocation=(self), camera=(), microphone=(), autoplay=(self "https://youtube.com")
Permissions-Policy: sync-xhr=(), document-domain=()

Часто отключаемые фичи

ФичаОпасность
sync-xhrблокирующие запросы → плохой UX
document-domainослабление SOP → уязвимости
picture-in-pictureUX-спам
usb, serial, hidдоступ к устройствам

Совет: Отключайте всё по умолчанию, включайте выборочно.


🔹 Диагностика: типичные проблемы и как их выявить

ПроблемаСимптомыИнструменты диагностикиРешение
Некорректный Content-TypeJS не выполняется, JSON парсится как текстDevTools → Network → Headers → Content-TypeУказать Content-Type: application/json; charset=utf-8
Отсутствует VaryCDN отдаёт неверную версию (например, gzip без Accept-Encoding)curl -H "Accept-Encoding: gzip" -I ... → сравнить Vary и телоДобавить Vary: Accept-Encoding, Accept
CORS failurefetch()TypeError: Failed to fetchDevTools → Console → CORS error; Network → HeadersПроверить Access-Control-Allow-Origin, Allow-Methods, Allow-Headers, Credentials
Куки не отправляютсяCookie отсутствует в запросеDevTools → Application → Cookies; Network → Request HeadersПроверить Secure, SameSite, Domain, Path, HttpOnly (не влияет на отправку)
Сессия «теряется»Пользователь разлогинивается при переходеЛоги сервера, Set-Cookie в ответахУбедиться, что Domain, Path согласованы; нет SameSite=Strict в кросс-сайтовых POST
Кэш не обновляетсяСтарый JS/CSS после деплояDevTools → Network → Disable cache (временно); curl -H "Cache-Control: no-cache" -I ...Добавить хэш в имя файла (app.a1b2c3.js), Cache-Control: immutable
HTTP/2 push не работаетPUSH_PROMISE не виденnghttp -v https://..., chrome://net-internals/#http2Убедиться, что сервер поддерживает push; браузер не отключил (chrome://flags/#enable-http2-push)
425 Too EarlyЗапросы падают при TLS 1.3 0-RTTЛоги сервера, curl --early-data ...Сервер должен возвращать 425, клиент — повторять без early data

🔹 Инструменты для работы с HTTP

ИнструментНазначениеПримеры использования
curlОтправка HTTP-запросов, отладка
curl -v -H "Accept: application/json" https://api.example.com
curl -X POST -d '{"key":"value"}' -H "Content-Type: application/json" ...
curl --compressed -H "Accept-Encoding: br,gzip" ...
nghttp / nghttp2HTTP/2 CLI-клиент/сервер
nghttp -nv https://http2.example.com — verbose, заголовки, фреймы
nghttp -u https://... — upgrade to H2C
h2specТестирование совместимости с HTTP/2
h2spec -k -p 443 example.com — проверка сервера на соответствие RFC
Wireshark / tsharkАнализ сетевого трафика
Фильтр: http2, tls.handshake.type == 1, http.request.method == "POST"
Декодирование HPACK/QPACK (требует ключи TLS для расшифровки)
DevTools (Chrome/Firefox)Отладка в браузере
Network → Headers, Timing, Initiator, Waterfall
Application → Cookies, Cache Storage
Security → Certificate, CSP, COOP/COEP
mitmproxyПрокси для инспекции и модификации трафика
Перехват HTTPS (требует установки CA), редактирование запросов/ответов, скрипты на Python
httpstatВизуализация времени запроса (аналог curl -w)
httpstat https://example.com → DNS, TCP, TLS, TTFB, total
hey / wrk / k6Нагрузочное тестирование
hey -n 10000 -c 100 -H "Authorization: Bearer ..." https://api.example.com